package com.ainibaby6.utils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.persistence.Id;
import javax.persistence.Query;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;

import play.db.jpa.JPA;
import play.db.jpa.JPABase;

public class ModelUtil
{
    public static <T> T queryField(String hql, Object... params)
    {
        List<T> list = queryFieldList(hql, params);
        if (CollectionUtils.isEmpty(list))
        {
            return null;
        }
        return list.get(0);
    }

    public static <T> List<T> queryFieldList(String hql, Object... params)
    {
        Query q = JPABase.em().createQuery(hql);
        if (!ArrayUtils.isEmpty(params))
        {
            for (int i = 0; i < params.length; i++)
            {
                q.setParameter(i + 1, params[i]);
            }
        }
        return q.getResultList();
    }

    private static Map<Class<?>, Field> idFieldMap = new HashMap<Class<?>, Field>();

    public static <T> int update(Class<?> clazz, Object id,
            Map<String, Object> values)
    {
        StringBuilder builder = new StringBuilder("update ").append(
                clazz.getName()).append(" set ");
        for (String key : values.keySet())
        {
            builder.append(key).append("=?,");
        }
        builder.deleteCharAt(builder.length() - 1);
        builder.append("where ").append(getIdFieldOf(clazz).getName())
                .append("=?");
        Query q = JPA.em().createQuery(builder.toString());
        int index = 1;
        for (Object value : values.values())
        {
            q.setParameter(index, value);
            index++;
        }
        q.setParameter(index, id);
        return q.executeUpdate();
    }

    private static Field getIdFieldOf(Class<?> clazz)
    {
        Field f = null;
        if ((f = idFieldMap.get(clazz)) != null)
        {
            return f;
        }
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields)
        {
            if (field.isAnnotationPresent(Id.class))
            {
                idFieldMap.put(clazz, field);
                return field;
            }
        }
        return null;
    }
}
